/**
 *******************************************************************************
 * @FileName  : sys_svc.h
 * @Author    : GaoQiu
 * @CreateDate: 2020-05-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */
#include "sys_svc.h"
#include "svc_handle.h"

#include "stack/host/att_uuid.h"

#include "utils/byte_stream.h"


/**
 *------------------------------------------------------------------------------
 * GAP service
 *------------------------------------------------------------------------------
 */
static const uint8_t gapSvcUuid[] = { UINT16_TO_BYTES(ATT_UUID_GAP_SERVICE) };
static const uint16_t gapSvcLen = sizeof(gapSvcUuid);

/*! device name characteristic */
static const uint8_t devNameProp[] ={
	ATT_PROP_READ|ATT_PROP_WRITE_NO_RSP,
	UINT16_TO_BYTES(GAP_DEVICE_NAME_HDL),
	UINT16_TO_BYTES(ATT_UUID_DEVICE_NAME),
};
static const uint16_t devNamePropLen = sizeof(devNameProp);

/*! device name */
static const uint8_t devNameUuid[] = {UINT16_TO_BYTES(ATT_UUID_DEVICE_NAME)};
uint8_t devName[30] = {"HID"};
uint16_t devNameLen = sizeof(devName);


/*! appearance characteristic */
static const uint8_t appearanceProp[] ={
	ATT_PROP_READ,
	UINT16_TO_BYTES(GAP_APPEARANCE_HDL),
	UINT16_TO_BYTES(ATT_UUID_APPEARANCE),
};
static const uint16_t appearancePropLen = sizeof(appearanceProp);

/*! appearance */
static const uint8_t appearanceUuid[] = {UINT16_TO_BYTES(ATT_UUID_APPEARANCE)};
uint8_t appearance[] = {UINT16_TO_BYTES(961)}; //keyboard
uint16_t appearanceLen = sizeof(appearance);

//GATT_CHARACTER_DEFINE(pUuid, pValue, pLen, maxLen, settings, attPerim)
static const AttsAttr_t gapAttrs[] = {

    /* GAP Service */
	GATT_CHARACTER_DEFINE(primSvcUuid, gapSvcUuid, &gapSvcLen, sizeof(gapSvcUuid), ATTS_SET_NONE, ATTS_PERMIT_READ)

	/* Device */
	GATT_CHARACTER_DEFINE(charDecUuid, devNameProp, &devNamePropLen, sizeof(devNameProp), ATTS_SET_NONE, ATTS_PERMIT_READ)
	GATT_CHARACTER_DEFINE(devNameUuid, devName, &devNameLen, sizeof(devName), ATTS_SET_NONE, ATTS_PERMIT_READ|ATTS_PERMIT_WRITE)

	/* Appearance */
	GATT_CHARACTER_DEFINE(charDecUuid, appearanceProp, &appearancePropLen, sizeof(appearanceProp), ATTS_SET_NONE, ATTS_PERMIT_READ)
	GATT_CHARACTER_DEFINE(appearanceUuid, appearance, &appearanceLen, sizeof(appearance), ATTS_SET_NONE, ATTS_PERMIT_READ)
};

AttsGroup_t gapGrp = {
	.pNext = NULL,
	.pAttr = (AttsAttr_t*)&gapAttrs[0],
	.readCback   = NULL,
	.writeCback  = NULL,
	.startHandle = GAP_START_HDL,
	.endHandle   = GAP_END_HDL,
};


/**
 *------------------------------------------------------------------------------
 * GATT service
 *------------------------------------------------------------------------------
 */
/*! service */
static const uint8_t gattValSvc[] = {UINT16_TO_BYTES(ATT_UUID_GATT_SERVICE)};
static const uint16_t gattLenSvc = sizeof(gattValSvc);

/*! service changed characteristic */
static const uint8_t gattValScCh[] = {ATT_PROP_INDICATE, UINT16_TO_BYTES(GATT_SC_HDL), UINT16_TO_BYTES(ATT_UUID_SERVICE_CHANGED)};
static const uint16_t gattLenScCh = sizeof(gattValScCh);

/*! service changed */
static const uint8_t serviceChangedUuid[] ={ UINT16_TO_BYTES(ATT_UUID_SERVICE_CHANGED)};
static uint8_t gattValSc[] = {UINT16_TO_BYTES(0x0001), UINT16_TO_BYTES(0xFFFF)};
static const uint16_t gattLenSc = sizeof(gattValSc);

/*! service changed client characteristic configuration */
static uint8_t gattValScChCcc[] = {UINT16_TO_BYTES(0x0000)};
static const uint16_t gattLenScChCcc = sizeof(gattValScChCcc);

/*! Attribute list for GATT group */
static const AttsAttr_t gattAttrs[] =
{
  {
    (uint8_t*)&primSvcUuid,
    (uint8_t *)gattValSvc,
    (uint16_t *)&gattLenSvc,
    sizeof(gattValSvc),
    0,
    ATTS_PERMIT_READ
  },
  {
    (uint8_t *)&charDecUuid,
    (uint8_t *) gattValScCh,
    (uint16_t *) &gattLenScCh,
    sizeof(gattValScCh),
    0,
    ATTS_PERMIT_READ
  },
  {
    serviceChangedUuid,
    (uint8_t *) gattValSc,
    (uint16_t *) &gattLenSc,
    sizeof(gattValSc),
    0,
    ATTS_PERMIT_READ
  },
  {
    clientCharCfgUuid,
    gattValScChCcc,
    (uint16_t *) &gattLenScChCcc,
    sizeof(gattValScChCcc),
    ATTS_SET_CCC,
    ATTS_PERMIT_READ | ATTS_PERMIT_WRITE
  },
};

//GATT_SVC_GRP_DECLARE(gattGrp, gattAttrs, NULL, NULL, GATT_START_HDL, GATT_END_HDL)
AttsGroup_t gattGrp ={
	  NULL,
	  (AttsAttr_t *)&gattAttrs[0],
	  NULL,
	  NULL,
	  GATT_START_HDL,
	  GATT_END_HDL
};

AttsCccSets_t ServerCccSets[] =
{
	[0] = {GATT_SC_CH_CCC_HDL, DM_SEC_LEVEL_NONE},

	[1] = {BATT_LVL_CH_CCC_HDL, DM_SEC_LEVEL_NONE},

	[2] = {HID_KEYBOARD_BOOT_IN_CH_CCC_HDL, DM_SEC_LEVEL_NONE},
	[3] = {HID_MOUSE_BOOT_IN_CH_CCC_HDL,  DM_SEC_LEVEL_NONE},
	[4] = {HID_INPUT_REPORT_1_CH_CCC_HDL, DM_SEC_LEVEL_NONE},
	[5] = {HID_INPUT_REPORT_2_CH_CCC_HDL, DM_SEC_LEVEL_NONE},
	[6] = {HID_INPUT_REPORT_3_CH_CCC_HDL, DM_SEC_LEVEL_NONE},

	[7] = {GW_TX_CH_CCC_HDL, DM_SEC_LEVEL_NONE},
	[8] = {HTS_TEMP_MEAS_CH_CCC_HDL, DM_SEC_LEVEL_NONE},
};
